package com.zzyl.nursing.service.impl;

import java.io.*;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.zzyl.common.ai.AIModelInvoker;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.IDCardUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.nursing.vo.HealthReportVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 健康评估Service业务层处理
 *
 * @author alexis
 * @date 2025-01-06
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;
    @Autowired
    private AIModelInvoker aiModelInvoker;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return healthAssessmentMapper.selectById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 新增健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public Long insertHealthAssessment(HealthAssessment healthAssessment) {
        //1.设计Prompt提示词（需要从Redis中获取当前身份证号对应的体检报告）
        String prompt = getPrompt(healthAssessment.getIdCard());
        //2.调用百度千帆大模型，分析报告结果，获取分析结果
        String result = aiModelInvoker.qianfanInvoker(prompt);
        System.out.println(result);
        //3.将分析结果保存到数据库中
        //分析数据
        //JSONUtil.toBean是用来将JSON字符串转换为Java对象。
        HealthReportVo healthReportVo = JSONUtil.toBean(result, HealthReportVo.class);

        //JSON.parseObject()  是用来将json字符串转换为Java对象。
//        HealthReportVo healthReportVo = JSON.parseObject(result, HealthReportVo.class);
        Long isCard = insertHealthReport(healthReportVo, healthAssessment);
        //4.返回结果数据对应的id
        return isCard;
    }

    private Long insertHealthReport(HealthReportVo healthReportVo, HealthAssessment healthAssessment) {
        //将数据存到的类中
        //老人身份证号码
        String idCard=healthAssessment.getIdCard();
        //出生日期
        healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(idCard));
        //年龄
        healthAssessment.setAge(IDCardUtils.getAgeByIdCard(idCard));
        //性别
        healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(idCard));
        //健康评估
        double healthScore = healthReportVo.getHealthAssessment().getHealthIndex();
        healthAssessment.setHealthScore(String.valueOf(healthScore));
        //风险等级
        healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel());
        //通过健康评估看是否建议入住
        healthAssessment.setSuggestionForAdmission(healthScore>=60?0:1);
        //通过健康评分计算一个推理的护理等级
        String levenlNameByHealthScore = getLevenlNameByHealthScore(healthScore);
        healthAssessment.setNursingLevelName(levenlNameByHealthScore);
        //统一设置未入住
        healthAssessment.setAdmissionStatus(1);
        //总检日期
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate());

        healthAssessment.setAssessmentTime(LocalDateTime.now());
        //报告总结
        healthAssessment.setReportSummary(healthReportVo.getSummarize());
        //疾病风险分布
        healthAssessment.setDiseaseRisk(JSON.toJSONString(healthReportVo.getRiskDistribution()));
        //异常分析
        healthAssessment.setAbnormalAnalysis(JSON.toJSONString(healthReportVo.getAbnormalData()));
        //八大系统评分
        healthAssessment.setSystemScore(JSON.toJSONString(healthReportVo.getSystemScore()));

        healthAssessmentMapper.insert(healthAssessment);


        return healthAssessment.getId();
    }

    private String getLevenlNameByHealthScore(double healthScore) {
        if (healthScore > 100 || healthScore < 0) {
            throw new BaseException("健康评分值不合法");
        }

        if (healthScore >= 90) {
            return "四级护理等级";
        } else if (healthScore >= 80) {
            return "三级护理等级";
        } else if (healthScore >= 70) {
            return "二级护理等级";
        } else if (healthScore >= 60) {
            return "一级护理等级";
        } else {
            return "特级护理等级";
        }
    }

    private String getPrompt(String idCard) {
        //1. this.getClass()
        //作用：获取当前对象的运行时类。
        //解释：this 是当前实例对象的引用，getClass() 返回该对象的实际运行时类（即 HealthAssessmentServiceImpl 类）。这确保了即使在继承链中也能正确找到资源文件。
        //2. getClass().getClassLoader()
        //作用：获取当前类的类加载器。
        //解释：类加载器负责将类文件加载到 JVM 中。通过 getClass().getClassLoader() 获取当前类的类加载器，以便后续使用该类加载器加载资源文件。
        //3. getClass().getClassLoader().getResourceAsStream("prompts\\healthReport.txt")
        //作用：从类路径下加载指定名称的资源文件，并返回一个 InputStream 对象。
        //解释：
        //"prompts\\healthReport.txt" 是资源文件的路径。注意这里使用了双反斜杠 \\ 来转义单个反斜杠 \，以避免编译错误。在实际项目中，通常推荐使用正斜杠 / 或者 File.separator 来提高跨平台兼容性。
        //getResourceAsStream 方法会根据类加载器查找类路径下的资源文件，并返回一个 InputStream 对象，用于读取文件内容。如果找不到该资源文件，则返回 null。
        //获取redis中缓存的从pdf文件中获取的文字

        try(
                InputStream is=this.getClass().getClassLoader().getResourceAsStream("prompts\\healthReport.txt");
                InputStreamReader isr= new InputStreamReader(is);
                BufferedReader br= new BufferedReader(isr);
        ) {
            String content = (String) redisTemplate.opsForHash().get(CacheConstants.HEALTH_REPORT, idCard);
            if (StringUtils.isEmpty(content)) {
                throw new BaseException("AI分析的文字为null");
            }
            //组装失败
//            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(
//            "D:\\java项目一\\zzyl-cp423\\zzyl-nursing-platform\\src\\main\\resources\\prompts\\healthReport.txt"),"UTF-8"));
            //BufferedReader br = new BufferedReader(new FileReader(
            //"D:\\java项目一\\zzyl-cp423\\zzyl-nursing-platform\\src\\main\\resources\\prompts\\healthReport.txt"));

            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
                if (line.contains("体验内容如下：")) {
                    sb.append(content);
                }
            }
            return sb.toString();
        } catch (IOException e) {
            throw new BaseException("提示词组装失败。");
        }
    }

    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.updateById(healthAssessment);
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return healthAssessmentMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return healthAssessmentMapper.deleteById(id);
    }
}
